home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Hacks
/
Hacks ’95
/
Grand Canyon Flythru
/
QD3D.c
< prev
next >
Wrap
Text File
|
1995-06-24
|
43KB
|
1,790 lines
//*********************************************************************************
//* QuickDraw 3D
//*
//* by Mark Sproul
//* (C) 1995
//*********************************************************************************
//* Edit history
//*********************************************************************************
//* Feb 27, 1995 Got QuickDraw 3D off of AppleLink
//* Mar 2, 1995 Got QD3D documentation off of AppleLink (6 Megs, 3 hrs to download)
//* Mar 4, 1995 Got QD3D rendering my data
//* Mar 5, 1995 Rendering DEM data
//* Mar 6, 1995 Able to render a full USGS-DEM data set (reduced to 75 by 75)
//* May 16, 1995 Starting a dialog with Apple about QD3D
//* May 17, 1995 Got 1.0 Beta of QD3D (new interfaces)
//* Jun 23, 1995 MacHack95, finnally got the shanding to work, enterd a movie in the contest
//*********************************************************************************
//#define _try_shader_
#define _ViewPlaneCamera_
//#define _USE_QD3D_LETTERS_
//#define _RENDER_TO_GWORLD_
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef __MEMORY__
#include <memory.h>
#endif
#include <keyequates.h>
#include "UHsetup.h"
#ifdef SYMANTEC_C
#include <math.h>
#include <MixedMode.h>
#define __CODEFRAGMENTS__
// #define kUnresolvedSymbolAddress kUnresolvedCFragSymbolAddress
#define kUnresolvedSymbolAddress 1
#define pi (3.1415926535898)
static float sinf(float x) { return(x);};
static float cosf(float x) { return(x);};
#endif
#ifndef __CODEFRAGMENTS__
#include <CodeFragments.h>
#endif
//#define ESCHER_VER_15 1
#include <QD3D.h>
#include <QD3DCamera.h>
#include <QD3DDrawContext.h>
#include <QD3DErrors.h>
#include <QD3DGroup.h>
#include <QD3DGeometry.h>
#include <QD3DIO.h>
#include <QD3DLight.h>
#include <QD3DMath.h>
#include <QD3DView.h>
#include <QD3DRenderer.h>
#include <QD3DSet.h>
#include <QD3DShader.h>
#include <QD3DStorage.h>
#include <vcInterface.h>
//* MLS Library includes
#include "CtoPfunc.proto.h"
#include "dialog.support.proto.h"
#include "DrawUtilities.proto.h"
#include "ErrorString.h"
#include "FSSpecToPath.h"
#include "keyDownUtilities.proto.h"
#include "LogWindow.h"
#include "utilities.proto.h"
#include "Image32.h"
#include "info_Block.typedefs.h"
#include "info_Block.proto.h"
//#include "Image32.menus.h"
#include "Image32.globals.h"
//#include "Image32.dialogs.h"
#include "Image32.proto.h"
#include "WindowStuff.proto.h"
#include "FileOpen.proto.h"
#include "FileSave.proto.h"
#include "MOOV_proto.h"
#include "QD3D_IM32.h"
TYPEwindowInfoPtr qd3d_info;
Boolean gQD3D_present = false;
Boolean gQD3D_viewer_present = false;
Boolean gQD3D_initialized = false;
long gRenderTotalTicks = 0;
long gRenderTicks;
TQ3Point3D gCameraFrom = { 0.0, 0.0, 15.0 };
TQ3Point3D gCameraTo = { 0.0, 0.0, 0.0 };
TQ3Vector3D gCameraUp = { 0.0, 1.0, 0.0 };
long *gSaveKeyMapSequence = nil;
long gSaveKeyMapIndex = 0;
#define kSaveKeyMapMax 4096
#if 0
TQ3ShaderObject gShader = nil;
#endif
#ifdef _ViewPlaneCamera_
TQ3ViewPlaneCameraData myViewCameraData;
#else
TQ3ViewAngleAspectCameraData myViewCameraData;
#endif
TQ3GroupObject GetTrigridData(Rect selectionRect, short scaleFactor);
//*********************************************************************************
static Boolean QD3D_CheckIfPresent(void)
{
Boolean qd3d_ok;
if ((void *)Q3Initialize == (void *)kUnresolvedSymbolAddress)
{
qd3d_ok = false;
}
else
{
qd3d_ok = true;
}
return(qd3d_ok);
}
//*********************************************************************************
static Boolean QD3D_CheckIfViewerPresent(void)
{
Boolean qd3d_ok;
if ((void *)Q3ViewerNew == (void *)kUnresolvedSymbolAddress)
{
qd3d_ok = false;
}
else
{
qd3d_ok = true;
}
return(qd3d_ok);
}
//*********************************************************************************
Boolean QD3D_Init(void)
{
TQ3Status myStatus;
TQ3Error qd3dError;
TQ3Error getError;
THz appZone;
gSaveKeyMapSequence = (long *)NewPtr(kSaveKeyMapMax * sizeof(long));
gQD3D_initialized = false;
gQD3D_present = QD3D_CheckIfPresent();
gQD3D_viewer_present = QD3D_CheckIfViewerPresent();
if (gQD3D_present)
{
myStatus = Q3Initialize(); //* initialize QuickDraw3D
if (myStatus == kQ3Success)
{
gQD3D_initialized = true;
}
else
{
getError = Q3Error_Get(&qd3dError);
DisplayErrorCode(qd3dError);
gQD3D_initialized = false;
}
}
if (sizeof(TQ3ViewObject) != sizeof(Ptr)) SysBeep(1);
if (sizeof(TQ3GroupObject) != sizeof(Ptr)) SysBeep(1);
if (sizeof(TQ3StyleObject) != sizeof(Ptr)) SysBeep(1);
if (sizeof(TYPEwindowInfo) != gSizeOfInfoStructure)
{
SysBeep(1);
PutAlertMessage("\pSometing is VERY wrong with info structure");
}
if (gQD3D_initialized)
{
//* check to see if modern memory manager is enabled
appZone = ApplicZone();
if ((appZone->heapType & kNewStyleHeap) == 0)
{
//* we ARE NOT running modern memory manger
PutAlertMessage("\pQD3D prefers to have Modern Memory Manger enabled");
}
}
return(gQD3D_initialized);
}
//*********************************************************************************
void QD3D_ShutDown(void)
{
TYPEwindowInfoPtr tinfo;
TQ3Status myStatus;
short ii, loopCnt;
short originalWindowCount;
//*****************************************************************************
//* it is VERY important that we close all QD3D windows, so go thru the list and
//* check for them
originalWindowCount = gNumWindows;
ii = 0;
loopCnt = 0;
while ((ii < gNumWindows) && (loopCnt < originalWindowCount))
{
tinfo = infoArray[ii];
if ((tinfo->wType == kWindType_3DMF_viewer) ||
(tinfo->pictureType == kPictureType_QD3Drendering))
{
DoCloseAWindow(tinfo);
}
else
{
ii++;
}
loopCnt++;
}
if (gQD3D_initialized)
{
myStatus = Q3Exit(); //* unload QuickDraw3D
}
}
#ifdef _USE_QD3D_LETTERS_
//*********************************************************************************
static TQ3GroupObject MyNewModel(void)
{
TQ3GroupObject myModel;
TQ3GeometryObject myBox;
TQ3BoxData myBoxData;
TQ3GroupPosition myGroupPosition;
//*Data for boxes comprising Hello and World block letters.
long ii;
float xorigin[34] = { -12, -9, -11, -7, -6, -6, -6, -2, -1, 3, 4,
8, 9, 9, 11, -13, -12, -11, -9, -7, -6, -6,
-4, -2, -1, -1, 1, 1, 3, 4, 8, 9, 9, 11};
float yorigin[34] = { 0, 0, 3, 0, 6, 3, 0, 0, 0, 0, 0, 0, 6, 0, 0,
-8, -8, -7, -8, -8, -8, -2, -8, -8, -2, -5, -4,
-8, -8, -8, -8, -8, -2, -7};
float height[34] = { 7, 7, 1, 7, 1, 1, 1, 7, 1, 7, 1, 7, 1, 1, 7,
7, 1, 3, 7, 7, 1, 1, 7, 7, 1, 1, 2, 3, 7, 1,
7, 1, 1, 5};
float width[34] = { 1, 1, 2, 1, 3, 2, 3, 1, 3, 1, 3, 1, 2, 2, 1,
1, 3, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 3,
1, 2, 2, 1};
#define kMaxPoints 34
/*Create an ordered display group for the complete model.*/
myModel = Q3DisplayGroup_New();
if (myModel != nil)
{
/*Add all the boxes to the model.*/
myBoxData.faceAttributeSet = nil;
myBoxData.boxAttributeSet = 0;
for (ii=0; ii<kMaxPoints; ii++)
{
Q3Point3D_Set(&myBoxData.origin, xorigin[ii], yorigin[ii], 1.0);
Q3Vector3D_Set(&myBoxData.orientation, 0, height[ii], 0);
Q3Vector3D_Set(&myBoxData.minorAxis, width[ii], 0, 0);
Q3Vector3D_Set(&myBoxData.majorAxis, 0, 0, 2);
myBox = Q3Box_New(&myBoxData);
myGroupPosition = Q3Group_AddObject(myModel, myBox);
Q3Object_Dispose(myBox); /*balance the reference count*/
if (myGroupPosition == nil)
goto bail;
}
}
else
{
SysBeep(1);
}
return (myModel); /*return the completed model*/
bail:
SysBeep(1);
/*If any of the above failed, then return an empty model.*/
return (nil);
}
#endif
//*********************************************************************************
static TQ3DrawContextObject MyNewDrawContext(WindowPtr theWindow)
{
TQ3DrawContextObject myDrawContext;
TQ3DrawContextData myDrawContextData;
TQ3MacDrawContextData myMacDrawContextData;
TQ3ColorARGB myClearColor = {0.0, 0.6, 0.9, 0.9};
//* Set the background color.
// Q3ColorRGB_Set(&myClearColor, .6, .9, .9);
#if 1
//* Fill in draw context data.
//+ myDrawContextData.clearImageState = kQ3True;
myDrawContextData.clearImageMethod = kQ3ClearMethodWithColor;
myDrawContextData.clearImageColor = myClearColor;
myDrawContextData.paneState = kQ3False;
myDrawContextData.maskState = kQ3False;
myDrawContextData.doubleBufferState = kQ3True;
//= myDrawContextData.activeBuffer = EcBackBuffer;
//+ myDrawContextData.activeBuffer = EcActiveBuffer_Back;
#else
//* Fill in draw context data.
myDrawContextData.clearImageState = kQ3True;
myDrawContextData.clearImageMethod = kQ3ClearMethodWithColor;
myDrawContextData.clearImageColor = myClearColor;
myDrawContextData.paneState = kQ3False;
myDrawContextData.maskState = kQ3False;
myDrawContextData.doubleBufferState = kQ3True;
//= myDrawContextData.activeBuffer = EcBackBuffer;
myDrawContextData.activeBuffer = EcActiveBuffer_Back;
#endif
//* Fill in Macintosh-specific draw context data.
myMacDrawContextData.drawContextData = myDrawContextData;
myMacDrawContextData.window = (CWindowPtr) theWindow;
//= myMacDrawContextData.EtMacDrawContext2DLibrary = kQ3Mac2DLibraryNone;
myMacDrawContextData.library = kQ3Mac2DLibraryNone;
myMacDrawContextData.viewPort = nil;
myMacDrawContextData.grafPort = nil;
//* Create draw context.
myDrawContext = Q3MacDrawContext_New(&myMacDrawContextData);
return (myDrawContext);
}
//*********************************************************************************
static TQ3CameraObject MyNewCamera (void)
{
TQ3CameraObject myCamera;
TQ3CameraData myCameraData;
//TQ3ViewAngleAspectCameraData myViewCameraData;
//TQ3Point3D gCameraFrom = { 0.0, 0.0, 15.0 };
//TQ3Point3D gCameraTo = { 0.0, 0.0, 0.0 };
//TQ3Vector3D gCameraUp = { 0.0, 1.0, 0.0 };
/*Fill in camera data.*/
//= myCameraData.placement.location = gCameraFrom;
myCameraData.placement.cameraLocation = gCameraFrom;
myCameraData.placement.pointOfInterest = gCameraTo;
myCameraData.placement.upVector = gCameraUp;
myCameraData.range.hither = .1;
// myCameraData.range.yon = 15.0;
myCameraData.range.yon = 1000.0;
myCameraData.viewPort.origin.x = -1.0;
myCameraData.viewPort.origin.y = 1.0;
myCameraData.viewPort.width = 2.0;
myCameraData.viewPort.height = 2.0;
//= myViewAngleCameraData.myViewAngleCameraData = myCameraData;
myViewCameraData.cameraData = myCameraData;
//+ myViewCameraData.fov = 100.0;
#ifdef _ViewPlaneCamera_
myViewCameraData.viewPlane = 15.0;
// myViewCameraData.halfWidthAtViewPlane = 14.0;
myViewCameraData.halfHeightAtViewPlane = 14.0;
myViewCameraData.centerXOnViewPlane = 0.0;
myViewCameraData.centerYOnViewPlane = 0.0;
myCamera = Q3ViewPlaneCamera_New(&myViewCameraData);
#else
myViewCameraData.aspectRatioXToY = 1;
myCamera = Q3ViewAngleAspectCamera_New(&myViewCameraData);
#endif
/*Return a camera.*/
return (myCamera);
}
//*********************************************************************************
static TQ3GroupObject MyNewLights (void)
{
TQ3GroupPosition myGroupPosition;
TQ3GroupObject myLightList;
TQ3LightData myLightData;
TQ3PointLightData myPointLightData;
TQ3DirectionalLightData myDirLightData;
TQ3LightObject myAmbientLight, myPointLight, myFillLight;
TQ3Point3D pointLocation = { -10.0, 0.0, 10.0 };
TQ3Vector3D fillDirection = { 10.0, 0.0, 10.0 };
TQ3ColorRGB WhiteLight = { 1.0, 1.0, 1.0 };
/*Set up light data for ambient light.*/
myLightData.isOn = kQ3True;
myLightData.brightness = .2;
myLightData.color = WhiteLight;
/*Create ambient light.*/
myAmbientLight = Q3AmbientLight_New(&myLightData);
if (myAmbientLight == nil)
goto bail;
/*Create a point light.*/
myLightData.brightness = 1.0;
myPointLightData.lightData = myLightData;
myPointLightData.castsShadows = kQ3False;
myPointLightData.attenuation = kQ3AttenuationTypeNone;
//= myPointLightData.location = &pointLocation;
myPointLightData.location = pointLocation;
myPointLight = Q3PointLight_New(&myPointLightData);
if (myPointLight == nil)
goto bail;
/*Create a directional light for fill.*/
myLightData.brightness = .2;
myDirLightData.lightData = myLightData;
myDirLightData.castsShadows = kQ3False;
//? myDirLightData.attenuation = kQ3AttenuationTypeNone;
//= myDirLightData.direction = &fillDirection;
myDirLightData.direction = fillDirection;
myFillLight = Q3DirectionalLight_New(&myDirLightData);
if (myFillLight == nil)
goto bail;
/*Create light group and add each of the lights to the group.*/
myLightList = Q3LightGroup_New();
if (myLightList == nil)
goto bail;
myGroupPosition = Q3Group_AddObject(myLightList, myAmbientLight);
Q3Object_Dispose(myAmbientLight); /*balance the reference count*/
if (myGroupPosition == 0)
goto bail;
myGroupPosition = Q3Group_AddObject(myLightList, myPointLight);
Q3Object_Dispose(myPointLight); /*balance the reference count*/
if (myGroupPosition == 0)
goto bail;
myGroupPosition = Q3Group_AddObject(myLightList, myFillLight);
Q3Object_Dispose(myFillLight); /*balance the reference count*/
if (myGroupPosition == 0)
goto bail;
return (myLightList);
bail:
SysBeep(1);
/*If any of the above failed, then return nothing!*/
return (nil);
}
//*********************************************************************************
static TQ3ViewObject MyNewView(WindowPtr theWindow)
{
TQ3Status myStatus;
TQ3ViewObject myView;
TQ3DrawContextObject myDrawContext;
TQ3RendererObject myRenderer;
TQ3CameraObject myCamera;
TQ3GroupObject myLights;
myView = Q3View_New();
//* Create and set draw context.
myDrawContext = MyNewDrawContext(theWindow);
if (myDrawContext == nil)
goto bail;
myStatus = Q3View_SetDrawContext(myView, myDrawContext);
Q3Object_Dispose(myDrawContext);
if (myStatus == kQ3Failure)
goto bail;
//* Create and set renderer.
#ifdef _try_shader_
myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeZBuffer);
// myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
#else
if (OptionKeyDown())
{
myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
}
else if (ControlKeyDown())
{
myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeGeneric);
}
else
{
myRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireFrame);
}
#endif
if (myRenderer == nil)
goto bail;
myStatus = Q3View_SetRenderer(myView, myRenderer);
Q3Object_Dispose(myRenderer);
if (myStatus == kQ3Failure)
goto bail;
/*Create and set camera.*/
#ifdef _ViewPlaneCamera_
myViewCameraData.halfWidthAtViewPlane = 14.0;
#else
myViewCameraData.fov = 100.0;
#endif
myCamera = MyNewCamera();
if (myCamera == nil)
goto bail;
myStatus = Q3View_SetCamera(myView, myCamera);
Q3Object_Dispose(myCamera);
if (myStatus == kQ3Failure)
goto bail;
/*Create and set lights.*/
myLights = MyNewLights();
if (myLights == nil)
goto bail;
myStatus = Q3View_SetLightGroup(myView, myLights);
Q3Object_Dispose(myLights);
if (myStatus == kQ3Failure)
goto bail;
return (myView);
bail:
SysBeep(1);
/*If any of the above failed, then don't return a view.*/
return (nil);
}
//*********************************************************************************
static void QD3D_RenderToGWorld(TYPEwindowInfoPtr tinfo, Boolean doInvalRect)
{
//WindowInfoHandle myWinfo;
TQ3Status myStatus;
TQ3DrawContextObject myDrawContext;
TQ3ViewStatus myViewStatus;
long startTicks, endTicks;
//CGrafPtr port;
//GDHandle gdh;
GrafPtr savePort;
if ((tinfo == nil) || (tinfo->wptr == nil) || (tinfo->osGWorld == nil) || (tinfo->qd3D_view == nil))
{
return;
}
// GetGWorld(&port, &gdh);
// SetGWorld(tinfo->osGWorld, nil);
GetPort(&savePort);
#ifdef _RENDER_TO_GWORLD_
SetPort((GrafPtr)tinfo->osGWorld);
#else
SetPort((GrafPtr)tinfo->wptr);
#endif
startTicks = TickCount();
//myWinfo = (WindowInfoHandle) GetWRefCon(theWindow);
//* Start rendering.
myStatus = Q3View_StartRendering(tinfo->qd3D_view);
if (myStatus == kQ3Success)
{
myViewStatus = kQ3ViewStatusRetraverse;
while ((myStatus == kQ3Success) && (myViewStatus == kQ3ViewStatusRetraverse))
{
#if 0
if (gShader != nil)
{
myStatus = Q3Style_Submit(gShader, tinfo->qd3D_view);
if (myStatus == kQ3Failure)
break;
}
#endif
if (tinfo->qd3D_interpolation != nil)
{
myStatus = Q3Style_Submit(tinfo->qd3D_interpolation, tinfo->qd3D_view);
if (myStatus == kQ3Failure)
break;
}
if (tinfo->qd3D_backfacing != nil)
{
myStatus = Q3Style_Submit(tinfo->qd3D_backfacing, tinfo->qd3D_view);
if (myStatus == kQ3Failure)
break;
}
if (tinfo->qd3D_fillstyle != nil)
{
myStatus = Q3Style_Submit(tinfo->qd3D_fillstyle, tinfo->qd3D_view);
if (myStatus == kQ3Failure)
break;
}
if (tinfo->qd3D_model != nil)
{
myStatus = Q3DisplayGroup_Submit(tinfo->qd3D_model, tinfo->qd3D_view);
if (myStatus == kQ3Failure)
break;
}
if (tinfo->qd3D_attributeSet != nil)
{
myStatus = Q3AttributeSet_Submit(tinfo->qd3D_attributeSet, tinfo->qd3D_view);
}
myViewStatus = Q3View_EndRendering(tinfo->qd3D_view);
}
//- while (myViewStatus == kQ3ViewStatusReTraverse);
//* End rendering.
myStatus = Q3View_GetDrawContext(tinfo->qd3D_view, &myDrawContext);
if (myStatus == kQ3Success)
{
//+ myStatus = ErDrawContext_UpdateFrontBuffer(myDrawContext);
Q3Object_Dispose(myDrawContext);
}
}
// SetGWorld(port, gdh);
SetPort(savePort);
if (doInvalRect)
{
//+ InvalWindowRect(tinfo);
}
endTicks = TickCount();
gRenderTicks = endTicks - startTicks;
gRenderTotalTicks += gRenderTicks;
}
//*********************************************************************************
static void CreateQD3D_Window(void)
{
CGrafPtr port;
GDHandle gdh;
long pixelsWide;
long pixelsTall;
short bitsDeep;
Boolean returnFlag;
Rect selectionRect;
short scaleFactor;
short scaleLimit;
if (gQD3D_initialized == false)
{
PutAlertMessage("\pSorry, but QD3D is not available");
return;
}
GetGWorld(&port, &gdh);
qd3d_info = info;
pixelsWide = 600;
pixelsTall = 400;
bitsDeep = 8;
returnFlag = AllocateAndCreateNewGWorldWindow( "\pQuick Draw 3D",
pixelsWide,
pixelsTall,
bitsDeep,
kPictureType_QD3Drendering,
true);
if (returnFlag)
{
SetGWorld(info->osGWorld, nil);
info->hasWorkToDo = true;
info->viewLocation.x = 0.0;
info->viewLocation.y = 0.0;
info->viewLocation.z = 15.0;
info->viewBearing = 0.0;
gCameraFrom = info->viewLocation;
#ifdef _RENDER_TO_GWORLD_
info->qd3D_view = MyNewView((GrafPtr)info->osGWorld); //*Create a new view.
#else
info->qd3D_view = MyNewView((GrafPtr)info->wptr); //*Create a new view.
#endif
if (info->qd3D_view == nil)
goto bail;
SetRect(&selectionRect, 0, 0, qd3d_info->pixelsPerLine, qd3d_info->nlines);
scaleLimit = 75;
if (OptionKeyDown())
{
scaleLimit = 50;
}
scaleFactor = 1;
while (((qd3d_info->pixelsPerLine / scaleFactor) > scaleLimit) || ((qd3d_info->nlines / scaleFactor) > scaleLimit))
{
scaleFactor++;
}
info->imgDescript = (char *)NewPtr(64);
if (info->imgDescript != nil)
{
sprintf(info->imgDescript, "QuickDraw 3D Rendering, scale factor = %d", scaleFactor);
}
//* Create model to display.
#ifdef _USE_QD3D_LETTERS_
info->qd3D_model = MyNewModel(); /*see Listing 1-3 on page 1-19*/
#else
info->qd3D_model = GetTrigridData(selectionRect, scaleFactor);
#endif
if (info->qd3D_model == nil)
goto bail;
//* Configure the rendering styles.
info->qd3D_interpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone);
if (info->qd3D_interpolation == nil)
goto bail;
//+ info->qd3D_backfacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth);
// info->qd3D_backfacing = Q3BackfacingStyle_New(kQ3BackfacingStyleRemove);
info->qd3D_backfacing = Q3BackfacingStyle_New(kQ3BackfacingStyleFlip);
if (info->qd3D_backfacing == nil)
goto bail;
info->qd3D_fillstyle = Q3FillStyle_New(kQ3FillStyleFilled);
// info->qd3D_fillstyle = Q3FillStyle_New(kQ3FillStyleEdges);
if (info->qd3D_interpolation == nil)
goto bail;
QD3D_RenderToGWorld(info, true);
}
SetGWorld(port, gdh);
return;
bail:
SysBeep(1);
// /*If failed for any reason, then close the window.*/
// if (myWinfo != nil)
// DisposeHandle((Handle) myWinfo);
//if (myWindow != nil)
// DisposeWindow(myWindow);
SetGWorld(port, gdh);
return;
}
//*********************************************************************************
void QD3D_DisposeObjects(TYPEwindowInfoPtr tinfo)
{
TQ3Status qd3dStatus;
if ((tinfo == nil) || (tinfo->pictureType != kPictureType_QD3Drendering))
{
return;
}
if (tinfo->qd3D_fillstyle != nil)
{
qd3dStatus = Q3Object_Dispose(tinfo->qd3D_fillstyle);
tinfo->qd3D_fillstyle = nil;
}
if (tinfo->qd3D_backfacing != nil)
{
qd3dStatus = Q3Object_Dispose(tinfo->qd3D_backfacing);
tinfo->qd3D_backfacing = nil;
}
if (tinfo->qd3D_interpolation != nil)
{
qd3dStatus = Q3Object_Dispose(tinfo->qd3D_interpolation);
tinfo->qd3D_interpolation = nil;
}
if (tinfo->qd3D_model != nil)
{
qd3dStatus = Q3Object_Dispose(tinfo->qd3D_model);
tinfo->qd3D_model = nil;
}
if (tinfo->qd3D_view != nil)
{
qd3dStatus = Q3Object_Dispose(tinfo->qd3D_view);
tinfo->qd3D_view = nil;
}
}
//*********************************************************************************
void QD3D_DisposeViewer(TYPEwindowInfoPtr tinfo)
{
if (tinfo->viewer_3DMF != nil)
{
Q3ViewerDispose(tinfo->viewer_3DMF);
tinfo->viewer_3DMF = nil;
}
}
//*********************************************************************************
void QD3D_MenuCommand(void)
{
CreateQD3D_Window();
}
//*********************************************************************************
static void Recalc_FromAndTo(TYPEwindowInfoPtr tinfo, float deltaF, float deltaTheta)
{
#define kVectorMagnitude 30.0
//#define kVectorIncrement 2.0
float sinTheta;
float cosTheta;
float deltaX, deltaZ;
if (deltaTheta != 0)
{
tinfo->viewBearing += deltaTheta;
}
sinTheta = sinf(tinfo->viewBearing);
cosTheta = cosf(tinfo->viewBearing);
if (deltaF != 0)
{
deltaX = deltaF * sinTheta;
deltaZ = deltaF * cosTheta;
tinfo->viewLocation.x += deltaX;
tinfo->viewLocation.z -= deltaZ;
}
deltaX = kVectorMagnitude * sinTheta;
deltaZ = kVectorMagnitude * cosTheta;
gCameraTo.x = tinfo->viewLocation.x + deltaX;
gCameraTo.z = tinfo->viewLocation.z - deltaZ;
gCameraFrom = tinfo->viewLocation;
}
//*********************************************************************************
Boolean QD3D_DoKeyDownInWindow(TYPEwindowInfoPtr tinfo, char theChar, short keyModifiers)
{
Boolean weHandledIt;
#if 0
TQ3Status qd3dStatus;
TQ3CameraObject myCamera;
float deltaV;
float deltaTheta;
deltaV = 2.0;
deltaTheta = pi/90;
if (keyModifiers & optionKey)
{
deltaV *= 3.0;
deltaTheta *= 3.0;
}
weHandledIt = true;
switch(theChar)
{
case homeKey:
tinfo->viewLocation.x = 0.0;
tinfo->viewLocation.y = 0.0;
tinfo->viewLocation.z = 15.0;
tinfo->viewBearing = 0;
gCameraTo.x = 0;
gCameraTo.y = 0;
gCameraTo.z = 0;
Recalc_FromAndTo(tinfo, 0.0, 0.0);
gCameraUp.x = 0.0;
gCameraUp.y = 1.0;
gCameraUp.z = 0.0;
#ifndef _ViewPlaneCamera_
myViewCameraData.fov = 100.0;
#endif
break;
case endKey:
tinfo->viewLocation.x = 0.0;
tinfo->viewLocation.y = 0.0;
tinfo->viewLocation.z = tinfo->qd3d_zDepthMax - 15.0;
tinfo->viewBearing = pi;
gCameraTo.x = 0;
gCameraTo.y = 0;
gCameraTo.z = 0;
Recalc_FromAndTo(tinfo, 0.0, 0.0);
gCameraUp.x = 0.0;
gCameraUp.y = 1.0;
gCameraUp.z = 0.0;
#ifndef _ViewPlaneCamera_
myViewCameraData.fov = 100.0;
#endif
break;
case upArrowKey:
Recalc_FromAndTo(tinfo, deltaV, 0.0);
break;
case downArrowKey:
Recalc_FromAndTo(tinfo, -deltaV, 0.0);
break;
case leftArrowKey:
Recalc_FromAndTo(tinfo, 0.0, -deltaTheta);
break;
case rightArrowKey:
Recalc_FromAndTo(tinfo, 0.0, deltaTheta);
break;
case '8':
tinfo->viewLocation.y += deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.y += deltaV;
}
break;
case '2':
tinfo->viewLocation.y -= deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.y -= deltaV;
}
break;
case '4':
tinfo->viewLocation.x -= deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.x -= deltaV;
}
break;
case '6':
tinfo->viewLocation.x += deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.x += deltaV;
}
break;
case '7':
gCameraTo.x -= deltaV;
break;
case '9':
gCameraTo.x += deltaV;
break;
case pageUpKey:
tinfo->viewLocation.y += deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.y += deltaV;
}
break;
case pageDnKey:
tinfo->viewLocation.y -= deltaV;
if (keyModifiers & shiftKey)
{
gCameraTo.y -= deltaV;
}
break;
case 0x20:
if (tinfo->movieBeingSaved)
{
WriteFrameToMOOVieFile(tinfo, gMovieRefNum);
SysBeep(1);
}
break;
default:
weHandledIt = false;
break;
}
gCameraFrom = tinfo->viewLocation;
//* Create and set camera.
myCamera = MyNewCamera();
if (myCamera != nil)
{
qd3dStatus = Q3View_SetCamera(info->qd3D_view, myCamera);
Q3Object_Dispose(myCamera);
QD3D_RenderToGWorld(tinfo, false);
#ifdef _RENDER_TO_GWORLD_
UpdateWindowFromGWorld(tinfo, kUpdate_fast);
#endif
}
else
{
SysBeep(1);
}
#else
weHandledIt = true;
#endif
return(weHandledIt);
}
//*********************************************************************************
static void ProcessQD3D_KeyMAP(TYPEwindowInfoPtr tinfo, KeyMap keyMap)
{
Boolean needToRender;
Boolean shiftKeyWasDown = false;
Boolean capsLockyWasDown = false;
float deltaV;
float deltaTheta;
TQ3CameraObject myCamera;
TQ3Status qd3dStatus;
deltaV = 0.75;
deltaTheta = pi/120;
needToRender = false;
if (keyMap[1] & 0x000004) //* option key
{
deltaV *= 3.0;
deltaTheta *= 3.0;
}
if (keyMap[1] & 0x000001) //* shift key
{
shiftKeyWasDown = true;
}
if (keyMap[1] & 0x000002) //* caps lock key
{
capsLockyWasDown = true;
}
if (keyMap[3] & 0x000040) //* up arrow
{
Recalc_FromAndTo(tinfo, deltaV, 0.0);
needToRender = true;
}
if (keyMap[3] & 0x000020) //* down arrow
{
Recalc_FromAndTo(tinfo, -deltaV, 0.0);
needToRender = true;
}
if (keyMap[3] & 0x000008) //* left arrow
{
Recalc_FromAndTo(tinfo, 0.0, -deltaTheta);
needToRender = true;
}
if (keyMap[3] & 0x000010) //* right arrow
{
Recalc_FromAndTo(tinfo, 0.0, deltaTheta);
needToRender = true;
}
if (keyMap[3] & 0x000800) //* home key
{
tinfo->viewLocation.x = 0.0;
tinfo->viewLocation.y = 0.0;
tinfo->viewLocation.z = 15.0;
tinfo->viewBearing = 0;
gCameraTo.x = 0;
gCameraTo.y = 0;
gCameraTo.z = 0;
Recalc_FromAndTo(tinfo, 0.0, 0.0);
gCameraUp.x = 0.0;
gCameraUp.y = 1.0;
gCameraUp.z = 0.0;
#ifndef _ViewPlaneCamera_
myViewCameraData.fov = 100.0;
#endif
needToRender = true;
}
if (keyMap[3] & 0x008000) //* end key
{
tinfo->viewLocation.x = 0.0;
tinfo->viewLocation.y = 0.0;
tinfo->viewLocation.z = tinfo->qd3d_zDepthMax - 15.0;
tinfo->viewBearing = pi;
gCameraTo.x = 0;
gCameraTo.y = 0;
gCameraTo.z = 0;
Recalc_FromAndTo(tinfo, 0.0, 0.0);
gCameraUp.x = 0.0;
gCameraUp.y = 1.0;
gCameraUp.z = 0.0;
#ifndef _ViewPlaneCamera_
myViewCameraData.fov = 100.0;
#endif
needToRender = true;
}
if (keyMap[2] & 0x000008) //* '8' key
{
tinfo->viewLocation.y += deltaV;
if (shiftKeyWasDown)
{
gCameraTo.y += deltaV;
}
needToRender = true;
}
if (keyMap[2] & 0x001000) //* '2' key
{
tinfo->viewLocation.y -= deltaV;
if (shiftKeyWasDown)
{
gCameraTo.y -= deltaV;
}
needToRender = true;
}
if (needToRender)
{
gCameraFrom = tinfo->viewLocation;
//* Create and set camera.
myCamera = MyNewCamera();
if (myCamera != nil)
{
qd3dStatus = Q3View_SetCamera(info->qd3D_view, myCamera);
Q3Object_Dispose(myCamera);
QD3D_RenderToGWorld(tinfo, false);
#ifdef _RENDER_TO_GWORLD_
UpdateWindowFromGWorld(tinfo, kUpdate_fast);
#endif
}
// if (tinfo->movieBeingSaved && capsLockyWasDown)
if (tinfo->movieBeingSaved)
{
WriteFrameToMOOVieFile(tinfo, gMovieRefNum);
}
}
else if (keyMap[0] || keyMap[1] || keyMap[2] || keyMap[3])
{
needToRender = false;
}
}
//*********************************************************************************
static void DoAllKeyStrokes(TYPEwindowInfoPtr tinfo)
{
KeyMap keyMap;
long ii;
ii = 0;
while (ii<gSaveKeyMapIndex)
{
keyMap[0] = gSaveKeyMapSequence[ii++];
keyMap[1] = gSaveKeyMapSequence[ii++];
keyMap[2] = gSaveKeyMapSequence[ii++];
keyMap[3] = gSaveKeyMapSequence[ii++];
ProcessQD3D_KeyMAP(tinfo, keyMap);
if (CommandPeriod())
{
break;
}
}
}
//*********************************************************************************
void DoBackground_QD3D(TYPEwindowInfoPtr tinfo)
{
KeyMap keyMap;
Boolean processKey;
GetKeys(keyMap);
processKey = true;
if (gSaveKeyMapSequence != nil)
{
if (keyMap[1] & 0x000800) //* back space key
{
gSaveKeyMapIndex--;
if (gSaveKeyMapIndex < 0)
{
gSaveKeyMapIndex = 0;
}
}
else if (keyMap[1] & 0x002000) //* escape
{
SysBeep(1);
gSaveKeyMapIndex = 0;
}
else if (keyMap[3] & 0x004) //* f1 key
{
SysBeep(1);
SysBeep(1);
DoAllKeyStrokes(tinfo);
}
else
{
if (gSaveKeyMapIndex < kSaveKeyMapMax)
{
gSaveKeyMapSequence[gSaveKeyMapIndex++] = keyMap[0];
gSaveKeyMapSequence[gSaveKeyMapIndex++] = keyMap[1];
gSaveKeyMapSequence[gSaveKeyMapIndex++] = keyMap[2];
gSaveKeyMapSequence[gSaveKeyMapIndex++] = keyMap[3];
}
else
{
SysBeep(1);
SysBeep(1);
SysBeep(1);
}
}
}
if (processKey)
{
ProcessQD3D_KeyMAP(tinfo, keyMap);
}
}
#ifdef _try_shader_
//*********************************************************************************
static TQ3AttributeSet GetPixmapTextureAttributeSet(EtPixmap myPixmap)
{
EtShaderObject myShader;
TQ3AttributeSet myAttrSet;
EtTextureObject myTexture;
TQ3Status myResult;
//* create a new texture from the pixmap passed in
myTexture = ErPixmapTexture_New(&myPixmap);
if (myTexture == NULL)
return (nil);
//* create a new texture shader from the texture
myShader = ErTextureShader_New(myTexture);
if (myShader == NULL)
return (nil);
/*create a new empty attribute set*/
myAttrSet = ErAttributeSet_New();
if (myAttrSet == NULL)
return (nil);
/*add the texture shader to the attribute set*/
myResult = ErAttributeSet_Add(myAttrSet, EcAttributeType_SurfaceShader, (void *)myShader);
if (myResult == kQ3Failure)
return (nil);
return(myAttrSet);
}
#endif
#ifndef _USE_QD3D_LETTERS_
//*********************************************************************************
static TQ3GroupObject GetTrigridData(Rect selectionRect, short scaleFactor)
{
TYPEwindowInfoPtr tinfo;
PixMapHandle myOsPixMapHandle; //* offscreen pixel map
Ptr scrnPtr;
Ptr rowPtr;
long sBytesPerRow;
long ii, jj;
short pixelsWide, pixelsTall;
short pixelValue;
TQ3GroupObject myGroup;
TQ3TriGridData myTriGridData;
TQ3Vertex3D *myVertices;
//TQ3AttributeSet *myFaceAtributes;
//unsigned long rowIndex, columnIndex;
TQ3Point3D position;
//TQ3Status myStatus;
TQ3GroupPosition myGroupPosition;
TQ3GeometryObject myTriGridDataObject;
TQ3Param2D param2D;
long myVertIndex;
long max_VertIndex;
short minPixValue, maxPixValue;
float pixelRange;
float pixelFloat;
long iiScaled;
long jjScaled;
short image_nlines;
short image_pixelsPerLine;
#ifdef _try_shader_
// TQ3Status myResult;
// EtShaderObject myShader;
TQ3AttributeSet myAttributeSet;
TQ3Pixmap myPixmap;
// TQ3Status qd3dStatus;
#endif
TQ3ShaderObject myIlluminationShader;
tinfo = qd3d_info;
if (tinfo == nil)
{
return(nil);
}
if (tinfo->pixelDepth != 8)
{
return(nil);
}
//**********************************************************************
myOsPixMapHandle = GetGWorldPixMap(tinfo->osGWorld);
LockPixels(myOsPixMapHandle);
scrnPtr = GetPixBaseAddr(myOsPixMapHandle);
sBytesPerRow = (*myOsPixMapHandle)->rowBytes & 0x3fff;
rowPtr = scrnPtr;
//**********************************************************************
pixelsWide = tinfo->pixelsPerLine / scaleFactor;
pixelsTall = tinfo->nlines / scaleFactor;
//**********************************************************************
//* This is sortof weird,
//* we need the Horz and Vert to be even
if ((pixelsWide % 2) != 0)
{
pixelsWide -= 1;
}
if ((pixelsTall % 2) != 0)
{
pixelsTall -= 1;
}
image_nlines = scaleFactor * pixelsTall;
image_pixelsPerLine = scaleFactor * pixelsWide;
//* add 2 to the height for a front step and a back step
pixelsTall += 2;
max_VertIndex = pixelsWide * pixelsTall;
myVertices = (TQ3Vertex3D *)NewPtrClear(max_VertIndex * sizeof(TQ3Vertex3D));
// myFaceAtributes = (TQ3AttributeSet *)NewPtrClear(pixelsWide * pixelsTall * sizeof(TQ3AttributeSet));
myTriGridData.triGridAttributeSet = 0;
#ifdef _try_shader_
myPixmap.image = GetPixBaseAddr(myOsPixMapHandle);
myPixmap.width = tinfo->pixelsPerLine;
myPixmap.height = tinfo->nlines;
myPixmap.rowBytes = (*myOsPixMapHandle)->rowBytes & 0x3fff;
myPixmap.pixelSize = 8;
myPixmap.pixelType = EcPixelType_RGB8;
myPixmap.bitOrder = EcEndian_Big;
myPixmap.byteOrder = EcEndian_Big;
myAttributeSet = GetPixmapTextureAttributeSet(myPixmap);
// myAttributeSet = ErAttributeSet_New();
// myShader = Q3PhongIllumination_New();
if (myAttributeSet != nil)
{
myTriGridData.triGridAttributeSet = myAttributeSet;
}
#endif
// myTriGridData.numUVertices = pixelsWide;
// myTriGridData.numVVertices = pixelsTall;
myTriGridData.numRows = pixelsWide;
myTriGridData.numColumns = pixelsTall;
myTriGridData.vertices = myVertices;
myTriGridData.facetAttributeSet = nil;
//**********************************************************************
//* first go thru and find the min and max pixel value
minPixValue = 255;
maxPixValue = 0;
for (ii=0; ii<tinfo->nlines; ii +=scaleFactor)
{
for (jj=0; jj<tinfo->pixelsPerLine; jj +=scaleFactor)
{
pixelValue = rowPtr[jj] & 0x00ff;
if (pixelValue < minPixValue)
{
minPixValue = pixelValue;
}
if (pixelValue > maxPixValue)
{
maxPixValue = pixelValue;
}
}
rowPtr += sBytesPerRow * scaleFactor;
}
pixelRange = maxPixValue - minPixValue;
//**********************************************************************
//* now go thru the image again and figure out the values
myVertIndex = 0;
info->qd3d_zDepthMax = 0.0; //* this DOES go to info, NOT tinfo
//* the U/V space is rotated 90 degrees from what we are used to,
//* we are going to start at the bottom, and move up and then right
//* to fill in the vertice values
//? rowPtr = scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
rowPtr = scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
for (jj=0; jj<image_pixelsPerLine; jj +=scaleFactor)
{
//* this is so the front is very low
if (myVertIndex < max_VertIndex)
{
jjScaled = jj / scaleFactor;
position.x = (1.0 * jjScaled) - (pixelsTall / 2.0);
position.z = 0;
position.y = -16.0;
myVertices[myVertIndex].point = position;
myVertIndex++;
}
rowPtr = scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
for (ii=0; ii<image_nlines; ii +=scaleFactor)
{
pixelValue = rowPtr[jj] & 0x00ff;
iiScaled = ii / scaleFactor;
jjScaled = jj / scaleFactor;
pixelFloat = pixelValue - minPixValue;
position.x = (1.0 * jjScaled) - (pixelsTall / 2.0);
position.z = -1.0 * iiScaled;
if (position.z < info->qd3d_zDepthMax) //* this DOES go to info, NOT tinfo
{
info->qd3d_zDepthMax = position.z; //* this DOES go to info, NOT tinfo
}
position.y = (pixelFloat / pixelRange) * 30.0;
position.y -= 15.0;
if (myVertIndex < max_VertIndex)
{
myVertices[myVertIndex].point = position;
#if 1
param2D.u = (myVertIndex % image_nlines) / ((float) image_pixelsPerLine);
param2D.v = 1.0 - ((myVertIndex / image_nlines) / ((float) (image_nlines - 1.0)));
myVertices[myVertIndex].attributeSet = Q3AttributeSet_New();
Q3AttributeSet_Add(myVertices[myVertIndex].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
#endif
myVertIndex++;
}
rowPtr -= sBytesPerRow * scaleFactor;
}
//* this is so the back is very low
if (myVertIndex < max_VertIndex)
{
iiScaled = ii / scaleFactor;
jjScaled = jj / scaleFactor;
position.x = (1.0 * jjScaled) - (pixelsTall / 2.0);
position.z = -1.0 * iiScaled;
position.y = -16.0;
myVertices[myVertIndex].point = position;
myVertIndex++;
}
}
UnlockPixels(myOsPixMapHandle);
//******************************
// code from MyNewModel
// myGroup = Q3OrderedDisplayGroup_New();
myGroup = Q3DisplayGroup_New();
myTriGridDataObject = Q3TriGrid_New(&myTriGridData);
if ((myGroup != nil) && (myTriGridDataObject != nil))
{
#if 1
myIlluminationShader = Q3PhongIllumination_New();
if (myIlluminationShader)
{
Q3Group_AddObject(myGroup, myIlluminationShader);
Q3Object_Dispose(myIlluminationShader);
}
#endif
myGroupPosition = Q3Group_AddObject(myGroup, myTriGridDataObject);
Q3Object_Dispose(myTriGridDataObject); /*balance the reference count*/
}
else
{
SysBeep(1);
}
return (myGroup); /*return the completed model*/
}
#endif
//*************************************************************************
Boolean OpenFile_3DMF(FSSpec *fsSpec)
{
long pixelsWide;
long pixelsTall;
short bitsDeep;
//ViewerObject viewer;
short fRefNum;
OSErr iErr;
Boolean returnFlag;
long longRefNum;
unsigned long viewerFlags;
if (gQD3D_viewer_present == false)
{
PutAlertMessage("\pSorry, but QD3D viewer is not available");
return(false);
}
pixelsWide = 600;
pixelsTall = 400;
bitsDeep = 8;
returnFlag = AllocateAndCreateNewWindow( fsSpec->name,
pixelsWide,
pixelsTall,
bitsDeep,
kWindType_3DMF_viewer,
kPictureType_3DMF,
gShowWindowOnOpenFlag);
if (returnFlag)
{
viewerFlags = vcDefault;
viewerFlags |= vcDrawFrame;
viewerFlags |= vcDraggingOff;
viewerFlags |= vcButtonTruck;
// viewerFlags |= vcButtonZoom;
// viewerFlags |= vcButtonDolly;
// create a viewer object
// viewer = Q3ViewerNew((CGrafPtr)info->wptr, &(info->wptr->portRect), vcDefault);
info->viewer_3DMF = Q3ViewerNew((CGrafPtr)info->wptr, &(info->wptr->portRect), viewerFlags);
// Open the file and get back a "fRefNum"
iErr = FSpOpenDF(fsSpec, fsRdPerm, &fRefNum);
if (iErr == noErr)
{
// Pass the fRefNum to viewer to read
longRefNum = fRefNum;
Q3ViewerUseFile(info->viewer_3DMF, longRefNum);
iErr = FSClose(fRefNum);
//****************************
// Draw it...
//* let update window handle the draw
//* Q3ViewerDraw(info->viewer_3DMF);
}
//********************************
// Dispose the viewer when done.
//* it will get disposed of when we close the window
// Q3ViewerDispose(viewer);
}
return(returnFlag);
}
//*************************************************************************
Boolean QD3D_Process3DMFviewerEvent(TYPEwindowInfoPtr tinfo, EventRecord *eventPtr)
{
Boolean eventHandled;
GrafPtr savePort;
eventHandled = false;
if (tinfo->viewer_3DMF)
{
GetPort(&savePort);
SetPort(tinfo->wptr);
eventHandled = Q3ViewerEvent(tinfo->viewer_3DMF, eventPtr);
if (eventHandled)
{
SysBeep(1);
}
SetPort(savePort);
}
return(eventHandled);
}
//*************************************************************************
void QD3D_3DMFviewerUpdateEvent(TYPEwindowInfoPtr tinfo, EventRecord *eventPtr)
{
GrafPtr savePort;
GetPort(&savePort);
SetPort(tinfo->wptr);
EraseRect(&tinfo->wptr->portRect);
if (tinfo->viewer_3DMF)
{
SetCursorWatch();
Q3ViewerDraw(tinfo->viewer_3DMF); //* draw the viewer
SetCursorArrow();
}
SetPort(savePort);
}
//*************************************************************************************
static void Write_3DMFScene( TYPEwindowInfoPtr tinfo,
TQ3FileObject file,
short textMode)
{
TQ3GroupPosition gPos;
TQ3Object object;
TQ3ViewStatus fileStatus;
TQ3Status status;
if (Q3File_OpenWrite(file, (textMode ? kQ3FileModeText : 0)) != kQ3Success)
{
SetCursor(&qd.arrow);
return;
}
Q3View_StartWriting(tinfo->qd3D_view, file);
#if 0
if (theDocument->viewHints != nil)
{
if (Q3Object_Submit(theDocument->viewHints, tinfo->qd3D_view) == kQ3Failure)
{
Q3File_Cancel(file);
SetCursor(&qd.arrow);
return;
}
}
#endif
fileStatus = kQ3ViewStatusRetraverse;
while (fileStatus == kQ3ViewStatusRetraverse)
{
if (tinfo->qd3D_model != nil)
{
Q3Group_GetFirstPosition(tinfo->qd3D_model, &gPos);
while (gPos)
{
Q3Group_GetPositionObject(tinfo->qd3D_model, gPos, &object);
status = Q3Object_Submit(object, tinfo->qd3D_view);
Q3Object_Dispose(object);
if (status != kQ3Failure)
{
Q3Group_GetNextPosition(tinfo->qd3D_model, &gPos);
}
}
}
fileStatus = Q3View_EndWriting(tinfo->qd3D_view);
}
}
//*************************************************************************************
Boolean SaveFile_3DMF( TYPEwindowInfoPtr tinfo,
FSSpec *fsSpec,
short fRefNum)
{
OSErr iErr;
//long length;
//char *bufPtr;
iErr = -1;
if (tinfo->qd3D_model)
{
TQ3StorageObject storage;
TQ3FileObject fd;
storage = Q3MacintoshStorage_New(fRefNum);
if (storage != nil)
{
fd = Q3File_New();
if (fd != nil)
{
Q3File_SetStorage(fd, storage);
Q3Object_Dispose(storage);
Write_3DMFScene(tinfo,
fd,
kQ3FileModeText) ;
Q3Object_Dispose(fd);
iErr = noErr;
}
}
}
return(iErr == noErr);
}